﻿#include "TextFileParser.h"
#include <QDebug>
#include <QTime>
#include <QPair>
#include <QVector>
#include <QString>
#include <vtkTable.h>
#include <vtkPoints.h>
#include <vtkSys/SystemTools.hxx>
#include <vtkDelimitedTextReader.h>
#include <vtkAbstractArray.h>
#include <vtkDoubleArray.h>

#include "CommonFunction.h"

namespace
{
    void permutationHelper(QVector<QVector<double>>& result,
        QVector<double>& tempList, QVector<QVector<double>>& inputLists, int depth)
    {
        if (tempList.size() == inputLists.size())
        {
            result.push_back(tempList);
            return;
        }

        for (int i = 0; i < inputLists[depth].size(); i++)
        {
            tempList.push_back(inputLists[depth][i]);
            permutationHelper(result, tempList, inputLists, depth + 1);
            tempList.pop_back();
        }
    }

    QVector<QVector<double>> permutation(QVector<QVector<double>>& inputLists)
    {
        QVector<QVector<double>> result;
        QVector<double> tempList;
        permutationHelper(result, tempList, inputLists, 0);
        return result;
    }
}

namespace pst
{
    TextFileParser::TextFileParser(QObject* parent)
        : QObject(parent)
        , m_fileName()
        , m_originalTable(nullptr)
        , m_reader(vtkDelimitedTextReader::New())
        , m_eachColNameOfKey()
        , m_eachColUnitOfKey()
        , m_eachColDataOfKey()
        , m_keyLenth(0)
        , m_eachColNameOfValue()
        , m_eachColUnitOfValue()
        , m_eachColDataOfValue()
        , m_valueLenth(0)
        , m_valueMatrix()
        , m_isSetLog{ false }
        , m_isSetNormalized{ false }
        , m_logFactory{ 10. }
        , m_scanParaIndex{ -1 }
        , m_chosenKeyList{}
        , m_chosenDataTable(vtkTable::New())
        , m_errorMessage()
    {
    }

    TextFileParser::~TextFileParser()
    {
        m_reader->Delete();
        m_chosenDataTable->Delete();
    }

    void TextFileParser::SetFileName(const QString& fileName)
    {
        m_fileName = fileName;
    }

    QString TextFileParser::GetFileName()
    {
        return m_fileName;
    }

    vtkDelimitedTextReader* TextFileParser::getTextReader()
    {
        return m_reader;
    }

    bool TextFileParser::Update()
    {
        qDebug() << "post dll read file begin" << QTime::currentTime();
        if (!readFile())
        {
            return false;
        }
        qDebug() << "post dll read file end" << QTime::currentTime();
        if (!parseTitleName())
        {
            return false;
        }
        return generateValueMatrix();
    }

    void TextFileParser::SetLogTheData(bool log)
    {
        m_isSetLog = log;
    }

    bool TextFileParser::GetLogTheData()
    {
        return m_isSetLog;
    }

    void TextFileParser::SetNormalizeTheData(bool normolized)
    {
        m_isSetNormalized = normolized;
    }

    bool TextFileParser::GetNormalizeTheData()
    {
        return m_isSetNormalized;
    }

    void TextFileParser::SetLogFactory(double factory)
    {
        m_logFactory = factory;
    }

    double TextFileParser::GetLogFactory()
    {
        return m_logFactory;
    }

    vtkTable* TextFileParser::getOriginalTable()
    {
        return m_originalTable;
    }

    QVector<QString> TextFileParser::getEachColNameOfKey()
    {
        return m_eachColNameOfKey;
    }

    QVector<QString> TextFileParser::getEachColUnitOfKey()
    {
        return m_eachColUnitOfKey;
    }

    QVector<QVector<double>> TextFileParser::getEachColDataOfKey()
    {
        return m_eachColDataOfKey;
    }

    QVector<QString> TextFileParser::getEachColNameOfValue()
    {
        return m_eachColNameOfValue;
    }

    QVector<QString> TextFileParser::getEachColUnitOfValue()
    {
        return m_eachColUnitOfValue;
    }

    QVector<QVector<double>> TextFileParser::getEachColDataOfValue()
    {
        return m_eachColDataOfValue;
    }

    QHash<QVector<double>, QVector<double>> TextFileParser::getValueMatrix()
    {
        return m_valueMatrix;
    }

    void TextFileParser::setScanParameterIndex(int index)
    {
        m_scanParaIndex = index;
    }

    int TextFileParser::getScanParameterIndex()
    {
        return m_scanParaIndex;
    }

    void TextFileParser::setOtherKeyParameter(const QVector<QVector<double>>& keyParaList)
    {
        m_chosenKeyList = keyParaList;
    }

    QVector<QVector<double>> TextFileParser::getOtherKeyParameter()
    {
        return m_chosenKeyList;
    }

    void TextFileParser::getChosenLinesFromKey(QList<int> valueId, vtkTable* returnTable)
    {
        // 给每个表格添加自变量列，即扫描参数列
        //auto scanArray = m_originalTable->GetColumn(m_scanParaIndex);//扫描参数列
        vtkNew<vtkDoubleArray> scanArray;
        QVector<double> scanList = m_eachColDataOfKey[m_scanParaIndex];
        scanArray->SetName(m_eachColNameOfKey[m_scanParaIndex].toStdString().c_str());
        for (int i = 0; i < scanList.size(); ++i)
        {
            scanArray->InsertNextTuple1(scanList[i]);
        }

        returnTable->RemoveAllColumns();//置空
        returnTable->AddColumn(scanArray);//扫描参数列作为自变量,第0列

        QVector<QVector<double>> keyList = permutation(m_chosenKeyList);
        //m_chosenDataTable->(keyList.size() + 1);//第0列为自变量，其他列为因变量


        // 每次循环产生valueId.size条曲线
        for (int i = 0; i < keyList.size(); ++i)
        {
            QVector<double> temp = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key

            //选择了查看几个value列，就产生多少个列
            QList<vtkSmartPointer<vtkDoubleArray>> tempArrayList;
            for (int m = 0; m < valueId.size(); ++m)
            {
                vtkNew<vtkDoubleArray> lineArray;
                tempArrayList.append(lineArray);
            }

            //组合生成曲线名字
            QString arrayName{};
            //arrayName += va //value列的名字
            for (int nameIndex = 0, j = 0; nameIndex < m_eachColNameOfKey.size(); ++nameIndex, ++j)
            {
                if (nameIndex == m_scanParaIndex)
                {
                    --j;
                    continue;
                }
                arrayName += QString(m_eachColNameOfKey[nameIndex]) + "=" + QString::number(temp[j]) + " ";
            }
            //lineArray->SetName(arrayName.toStdString().c_str()); //列名 根据temp获取


            for (int k = 0; k < scanArray->GetNumberOfTuples(); ++k)
            {
                QVector<double> temp = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key

                temp.insert(m_scanParaIndex, scanArray->GetVariantValue(k).ToDouble());//一个完整的Key
                auto value = m_valueMatrix.value(temp); //对应的值
                //可能取不到值 会报错
                for (int m = 0; m < valueId.size(); ++m)
                {
                    tempArrayList[m]->InsertNextTuple1(value[valueId[m]]);
                }
            }

            for (int m = 0; m < valueId.size(); ++m)
            {
                auto _tempArrayName = arrayName;
                _tempArrayName += m_eachColNameOfValue[valueId[m]];
                tempArrayList[m]->SetName(_tempArrayName.toStdString().c_str()); //列名 根据temp获取
                returnTable->AddColumn(tempArrayList[m]);
            }
        }
        //生成m个vtkTable,每个table中，第一列是自变量（扫描参数），其他列为对应的因变量数值，每列为一条曲线
    }

    void TextFileParser::getChosenLinesFromKey(QList<int> valueId,
        QList<InfomationCurve2DBasical>& yList)
    {
        yList.clear();
        QVector<QVector<double>> keyList = permutation(m_chosenKeyList);

        for (int i = 0; i < keyList.size(); ++i)
        {
            QVector<double> temp = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key

            QList<InfomationCurve2DBasical> tempValueList;
            InfomationCurve2DBasical info;
            info.setXData(qMakePair(m_eachColNameOfKey[m_scanParaIndex], m_eachColDataOfKey[m_scanParaIndex]));
            info.setScanParameterIndex(m_scanParaIndex);
            for (int i = 0; i < valueId.size(); i++) //分配存储空间
            {
                info.setOtherKeyData(temp);
                info.setReader(this);
                tempValueList.append(info);
            }

            //组合生成曲线名字
            QString arrayName{};
            //arrayName += va //value列的名字
            for (int nameIndex = 0, j = 0; nameIndex < m_eachColNameOfKey.size(); ++nameIndex, ++j)
            {
                if (nameIndex == m_scanParaIndex)
                {
                    --j;
                    continue;
                }
                arrayName += QString(m_eachColNameOfKey[nameIndex]) + "=" + QString::number(temp[j]) + " ";
            }

            for (int k = 0; k < m_eachColDataOfKey[m_scanParaIndex].size(); ++k)
            {
                QVector<double> temp = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key

                temp.insert(m_scanParaIndex, m_eachColDataOfKey[m_scanParaIndex][k]);//一个完整的Key
                auto value = m_valueMatrix.value(temp); //对应的值
                //可能取不到值 会报错
                for (int m = 0; m < valueId.size(); ++m)
                {
                    tempValueList[m].getYDataPointer()->second.append(value[valueId[m]]);
                    tempValueList[m].setValueIndex(valueId[m]);
                }
            }

            for (int m = 0; m < valueId.size(); ++m)
            {
                auto _tempArrayName = arrayName;
                _tempArrayName += m_eachColNameOfValue[valueId[m]];
                tempValueList[m].getYDataPointer()->first = _tempArrayName; //列名 根据temp获取
                yList.append(tempValueList[m]);
            }
        }
    }

    //应需求：每条曲线先归一化，再取对数，再转直角坐标。都是对单条曲线自身的操作
    void TextFileParser::getChosenPointsListFromKey(QList<int> valueId,
        QList<vtkSmartPointer<vtkPoints>>& resultPointsList, QList<vtkSmartPointer<vtkPoints>>& resultPointsList_sphere,
        QList<QString>& lineName, double radiusBestRange[2], bool log, bool normalize, double minValueWanted, bool enableCustomRange)
    {
        vtkNew<vtkDoubleArray> scanArray;
        QVector<double> scanList = m_eachColDataOfKey[m_scanParaIndex];
        scanArray->SetName(m_eachColNameOfKey[m_scanParaIndex].toStdString().c_str());
        for (int i = 0; i < scanList.size(); ++i)
        {
            scanArray->InsertNextTuple1(scanList[i]);//每一个扫描参数列 /theta = 0 , theta = 1, theta = 2 ...
        }

        QVector<QVector<double>> keyList = permutation(m_chosenKeyList);
        //m_chosenDataTable->(keyList.size() + 1);//第0列为自变量，其他列为因变量


        QVector<QVector<QVector<double>>> allCurvesMinMaxValueList;

        //获取所有曲线归一化取对数后的最小最大值 begin
        //获取所有曲线归一化取对数后的最小最大值 begin
        //获取所有曲线归一化取对数后的最小最大值 begin
        double chosenCurveMinValue = VTK_DOUBLE_MAX;  //全局最值
        double chosenCurveMaxValue = -VTK_DOUBLE_MAX; //全局最值

        for (int i = 0; i < keyList.size(); ++i)
        {
            //选择了查看几个value列，就产生多少个列
            QVector<QVector<double>> LineValueList; //取出每一个key对应的valueList  QList<"value1", "value2", "value3">

            for (int k = 0; k < scanArray->GetNumberOfTuples(); ++k)
            {
                QVector<double> tempKeys = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key
                tempKeys.insert(m_scanParaIndex, scanArray->GetVariantValue(k).ToDouble());//一个完整的Key
                auto valueList = m_valueMatrix.value(tempKeys); //对应的多个value值

                LineValueList.append(valueList);
            }

            if (LineValueList.empty())
            {
                return;
            }

            QVector<QVector<double>> minMaxValueList;
            for (int i = 0; i < valueId.size(); ++i)//按列取，取出 "value1", "value2", "value3"
            {
                //每一列值 如"value1"， "value2"， "value3"
                double minValue = VTK_DOUBLE_MAX;
                double maxValue = -VTK_DOUBLE_MAX;
                for (int j = 0; j < LineValueList.size(); ++j)
                {
                    if (LineValueList[j][i] > maxValue)
                    {
                        maxValue = LineValueList[j][i];
                    }
                    if (LineValueList[j][i] < minValue)
                    {
                        minValue = LineValueList[j][i];
                    }
                }
                minMaxValueList.append({ minValue,maxValue });
            }
            allCurvesMinMaxValueList.append(minMaxValueList);

            //计算全局最值
            if (!normalize && !log) //及不取对数也不归一化，使用原始值
            {
                for (int i = 0; i < minMaxValueList.size(); ++i)
                {
                    if (minMaxValueList[i][0] < chosenCurveMinValue)
                    {
                        chosenCurveMinValue = minMaxValueList[i][0];
                    }
                    if (minMaxValueList[i][1] > chosenCurveMaxValue)
                    {
                        chosenCurveMaxValue = minMaxValueList[i][1];
                    }
                }
            }
            else if (normalize && !log)//只归一化
                //每条曲线归一化，除以自己的最大值
            {
                for (int i = 0; i < minMaxValueList.size(); ++i)
                {
                    if (minMaxValueList[i][0] / minMaxValueList[i][1] < chosenCurveMinValue)
                    {
                        chosenCurveMinValue = minMaxValueList[i][0] / minMaxValueList[i][1];
                    }
                }
                chosenCurveMaxValue = 1;
            }
            else if (!normalize && log)//只取对数
            {
                for (int i = 0; i < minMaxValueList.size(); ++i)
                {
                    auto logMinValue = 10 * std::log10(minMaxValueList[i][0]);
                    auto logMaxValue = 10 * std::log10(minMaxValueList[i][1]);
                    if (logMinValue < chosenCurveMinValue)
                    {
                        chosenCurveMinValue = logMinValue;
                    }
                    if (logMaxValue > chosenCurveMaxValue)
                    {
                        chosenCurveMaxValue = logMaxValue;
                    }
                }
            }
            else //既归一化，又取对数
                 //先归一化，再取对数
            {
                for (int i = 0; i < minMaxValueList.size(); ++i)
                {
                    auto minV = 10 * std::log10(minMaxValueList[i][0] / minMaxValueList[i][1]);
                    if (minV < chosenCurveMinValue)
                    {
                        chosenCurveMinValue = minV;
                    }
                }
                chosenCurveMaxValue = 0;
            }
        }
        //获取所有曲线归一化取对数后的最小最大值 end
        //获取所有曲线归一化取对数后的最小最大值 end
        //获取所有曲线归一化取对数后的最小最大值 end

        radiusBestRange[0] = chosenCurveMinValue;
        radiusBestRange[1] = chosenCurveMaxValue;


        // 每次循环产生valueId.size条曲线
        for (int i = 0; i < keyList.size(); ++i)
        {
            QVector<double> temp = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key

            //选择了查看几个value列，就产生多少个列
            QList<vtkSmartPointer<vtkPoints>> tempArrayList;
            QList<vtkSmartPointer<vtkPoints>> tempArrayList_sphere;
            for (int m = 0; m < valueId.size(); ++m)
            {
                vtkNew<vtkPoints> lineArray;
                tempArrayList.append(lineArray);
                vtkNew<vtkPoints> lineArray_sphere;
                tempArrayList_sphere.append(lineArray_sphere);
            }

            //组合生成曲线名字
            QString arrayName{};
            for (int nameIndex = 0, j = 0; nameIndex < m_eachColNameOfKey.size(); ++nameIndex, ++j)
            {
                if (nameIndex == m_scanParaIndex)
                {
                    --j;
                    continue;
                }
                arrayName += QString(m_eachColNameOfKey[nameIndex]) + "=" + QString::number(temp[j]) + " ";
            }

            QVector<QVector<double>> lineKeyList; //每一个完整的key  QList<"key1", "key2", "key3">
            QVector<QVector<double>> LineValueList; //取出每一个key对应的valueList  QList<"value1", "value2", "value3">

            for (int k = 0; k < scanArray->GetNumberOfTuples(); ++k)
            {
                QVector<double> tempKeys = keyList[i]; //除扫描参数外，其他的key构成的list，取一个具体的key
                tempKeys.insert(m_scanParaIndex, scanArray->GetVariantValue(k).ToDouble());//一个完整的Key
                auto valueList = m_valueMatrix.value(tempKeys); //对应的多个value值

                lineKeyList.append(tempKeys);
                LineValueList.append(valueList);
            }

            //找出每一列value的最大最小值
            QVector<QVector<double>> minMaxValueList = allCurvesMinMaxValueList[i];//没有取对数、归一化
            QVector<QVector<double>> minMaxValueListNorLog = allCurvesMinMaxValueList[i];//取对数、归一化后的数据

            if (LineValueList.empty())
            {
                return;
            }

            //每一列值归一化、取对数、平移、转直角坐标
            for (int i = 0; i < valueId.size(); ++i)//按列取，取出 "value1", "value2", "value3"
            {
                //对最值进行归一化取对数
                if (normalize)
                {
                    minMaxValueListNorLog[i][0] = minMaxValueListNorLog[i][0] / minMaxValueListNorLog[i][1]; //最小值进行归一化
                    minMaxValueListNorLog[i][1] = 1;
                }
                if (log)
                {
                    minMaxValueListNorLog[i][0] = 10 * std::log10(minMaxValueListNorLog[i][0]); //最小值进行取对数
                    minMaxValueListNorLog[i][1] = 10 * std::log10(minMaxValueListNorLog[i][1]); //最大值进行取对数
                }


                ///处理数据
                for (int j = 0; j < LineValueList.size(); ++j)
                {
                    //每一列值 如"value1"， "value2"， "value3"
                    if (normalize)//归一化
                    {
                        if (qFuzzyCompare(minMaxValueList[i][1], 0.))
                        {
                            m_errorMessage += "Max value is zero while nomalizing the data! \n";
                            continue;
                        }
                        //LineValueList[j][i] = (LineValueList[j][i] - minMaxValueList[i][0]) / (minMaxValueList[i][1] - minMaxValueList[i][0]);//归一化到0-1版本
                        LineValueList[j][i] = LineValueList[j][i] / minMaxValueList[i][1];//直接除以最大值版本
                    }

                    if (log)//取对数
                    {
                        LineValueList[j][i] = 10 * std::log10(LineValueList[j][i]);
                    }

                    auto lineValue = LineValueList[j][i]; //用于转直角坐标系画图

                    //  计算新的数据范围 , lineValue此时是>=0的
                    if (enableCustomRange)
                    {
                        if (minMaxValueListNorLog[i][0] >= minValueWanted) //当前曲线最小值比想要的最小值大（或等），减去最小值
                        {
                            lineValue -= minValueWanted; //大减小 必为正(或0)
                        }
                        else //曲线最小值比想要的最小值更小
                        {
                            lineValue = std::max(lineValue, minValueWanted);
                            lineValue -= minValueWanted;
                        }
                    }
                    else
                    {
                        if (chosenCurveMinValue < 0) //与全局最小值比较
                        {
                            lineValue -= chosenCurveMinValue;
                        }
                    }


                    //转直角坐标
                    double x{ 0.0 };
                    double y{ 0.0 };
                    double z{ 0.0 };
                    //"Theta||deg||key","Phi||deg||key","Frequency||GHz||key","Gain||None||value"
                    // LineValueList[j][i] 为R
                    if (m_scanParaIndex == 1) //theta
                    {
                        CommonFunction::PolarToRectangularCoorSys(lineKeyList[j][1], lineValue, x, y);
                    }
                    else if (m_scanParaIndex == 0) //phi
                    {
                        CommonFunction::PolarToRectangularCoorSys(lineKeyList[j][0], lineValue, x, y);
                    }

                    tempArrayList[i]->InsertNextPoint(x, y, 0);
                    tempArrayList_sphere[i]->InsertNextPoint(lineKeyList[j][0], lineKeyList[j][1], LineValueList[j][i]);//数据操作后的原始值,用于拾取
                }
            }

            for (int m = 0; m < valueId.size(); ++m)
            {
                auto _tempArrayName = arrayName;
                _tempArrayName += m_eachColNameOfValue[valueId[m]];

                lineName.append(_tempArrayName);

                resultPointsList.append(tempArrayList[m]);
                resultPointsList_sphere.append(tempArrayList_sphere[m]);
            }
        }
    }


    QString TextFileParser::getErrorMessage() const
    {
        return m_errorMessage;
    }

    bool TextFileParser::readFile()
    {
        if (!vtksys::SystemTools::FileExists(m_fileName.toStdString(), true))
        {
            return false;
        }
        m_reader->SetFileName(m_fileName.toStdString().c_str());
        m_reader->SetHaveHeaders(true);
        m_reader->SetDetectNumericColumns(true);
        m_reader->SetFieldDelimiterCharacters(",");
        m_reader->SetUseStringDelimiter(true);
        m_reader->Update();

        if (m_reader->GetOutput() == nullptr)
        {
            return false;
        }
        m_originalTable = m_reader->GetOutput();
        return true;
    }

    bool TextFileParser::parseTitleName()
    {
        clearData();

        for (int i = 0; i < m_originalTable->GetNumberOfColumns(); ++i)
        {
            auto arrayName = CommonFunction::trim(m_originalTable->GetColumn(i)->GetName());
            std::vector<std::string> tempRes;
            CommonFunction::Stringsplit(arrayName, "||", tempRes);
            if (tempRes.size() != 3)
            {
                qDebug() << " Warning! File format illegal : " << m_fileName;
                m_errorMessage += "File format illegal!";
                return false;
            }

            //判断是key还是value
            auto type = CommonFunction::trim(tempRes[2]);
            transform(type.begin(), type.end(), type.begin(), ::toupper);
            if (type == "KEY")
            {
                m_eachColNameOfKey.append(QString::fromStdString(CommonFunction::trim(tempRes[0])));
                m_eachColUnitOfKey.append(QString::fromStdString(CommonFunction::trim(tempRes[1])));
            }
            else if (type == "VALUE")
            {
                m_eachColNameOfValue.append(QString::fromStdString(CommonFunction::trim(tempRes[0])));
                m_eachColUnitOfValue.append(QString::fromStdString(CommonFunction::trim(tempRes[1])));

            }
            else
            {
                qDebug() << " Warning! File format illegal, type is " << QString::fromStdString(type) << " in " << m_fileName;
                m_errorMessage += "File format illegal, type is " + QString::fromStdString(type);
                return false;
            }
        }
        m_keyLenth = m_eachColNameOfKey.size();
        m_valueLenth = m_eachColNameOfValue.size();
        return true;
    }

    void TextFileParser::clearData()
    {
        m_eachColNameOfKey.clear();
        m_eachColUnitOfKey.clear();
        m_eachColDataOfKey.clear();
        m_eachColNameOfValue.clear();
        m_eachColUnitOfValue.clear();
        m_eachColDataOfValue.clear();
        m_valueMatrix.clear();
        m_keyLenth = 0;
        m_valueLenth = 0;
    }

    bool TextFileParser::generateValueMatrix()
    {
        m_valueMatrix.clear();
        qDebug() << "generateValueMatrix function ====================begin ==============" << QTime::currentTime();
        for (int i = 0; i < m_keyLenth; ++i)
        {
            m_eachColDataOfKey.append(QVector<double>());
        }
        for (int i = 0; i < m_valueLenth; ++i)
        {
            m_eachColDataOfValue.append(QVector<double>());
        }

        for (int i = 0; i < m_originalTable->GetNumberOfRows(); ++i)        //多线程
        {
            QVector<double> keyList;
            QVector<double> valueList;
            for (int j = 0; j < m_keyLenth; ++j)//每一行的所有key列
            {
                bool isSuc = false;
                auto value = m_originalTable->GetValue(i, j).ToDouble(&isSuc);
                if (!isSuc)
                {
                    m_errorMessage += "File format illegal, data contains nonnumerical value ";
                    return false;
                }
                keyList.append(value);
                if (!m_eachColDataOfKey[j].contains(value))
                {
                    m_eachColDataOfKey[j].append(value);
                }
            }
            for (int j = m_keyLenth; j < m_originalTable->GetNumberOfColumns(); ++j)//每一行的所有value列
            {
                bool isSuc = false;
                auto value = m_originalTable->GetValue(i, j).ToDouble(&isSuc);
                if (!isSuc)
                {
                    m_errorMessage += "File format illegal, data contains nonnumerical value ";
                    return false;
                }
                valueList.append(value);
                m_eachColDataOfValue[j - m_keyLenth].append(value);
            }
            m_valueMatrix.insert(keyList, valueList);
        }


        // 去重？？
        //for (int i = 0; i < m_valueLenth; ++i)
        //{
        //    m_eachColDataOfValue[i].toSet().toList();
        //}
        qDebug() << "generateValueMatrix function ====================end ==============" << QTime::currentTime();
        return true;
    }
}
